<?php

namespace App\Models\System;

use App\Models\BaseModel;
use Illuminate\Database\Eloquent\Casts\Attribute;
use Illuminate\Support\Collection;
use Illuminate\Support\Facades\Cache;

class Dict extends BaseModel
{
    /**
     * 缓存key
     */
    public const CACHE_ALL_KEY = 'DICT_LIST';

    protected $fillable = [
        'title',
        'code',
    ];

    /**
     * @return array<string, string>
     */
    protected function casts(): array
    {
        return [
            'created_at' => 'datetime:Y-m-d H:i:s',
            'updated_at' => 'datetime:Y-m-d H:i:s',
        ];
    }

    protected function title(): Attribute
    {
        return new Attribute(
            get: fn ($value) => __($value),
        );
    }

    /**
     * 字典项
     */
    public function items(): \Illuminate\Database\Eloquent\Relations\HasMany
    {
        return $this->hasMany(DictItem::class, 'dict_id');
    }

    /**
     * 增加多个字典
     */
    public static function createDictItems($data): void
    {
        foreach ($data as $dict) {
            self::createItem($dict);
        }
    }

    /**
     * 创建字典和字典项
     * items为字典项的值
     */
    public static function createItem($dict): Dict
    {
        $row = new Dict;
        $row->fill($dict);
        $row->save();
        $items = [];
        foreach ($dict['items'] as $item) {
            $items[] = new DictItem($item);
        }
        $row->items()->saveMany($items);

        return $row;
    }

    /**
     * 根据code获取字典和字典项
     */
    public static function getDictByCode($code): ?Dict
    {
        $row = self::getAll()->where('code', $code)->first();
        if (! $row) {
            return null;
        }

        return $row;
    }

    public static function getDictItemsByCode($code): ?Collection
    {
        $row = self::getDictByCode($code);

        return $row?->items;
    }

    /**
     * 根据code和value获取字典项的title
     */
    public static function getItemTitle($code, $value): string
    {
        // 通过code获取字典
        $dict = self::getAll()->get($code);
        if (! $dict) {
            return 'unknown';
        }
        // 通过值去拿项
        $item = $dict->items->get($value);
        if (! $item) {
            return 'unknown';
        }

        return $item->title;
    }

    /**
     * 获取所有字典
     */
    public static function getAll(): Collection
    {
        // 使用缓存
        return Cache::rememberForever(self::CACHE_ALL_KEY, function () {
            // 查询所有的字典
            $list = self::query()->with('items')->get();
            $list->setVisible(['id', 'title', 'code', 'items']);

            // 字典的code作为键
            return $list->map(function ($dict) {
                // 字典项的value作为键
                $dict->items = $dict->items->keyBy('value')->setVisible(['id', 'title', 'code', 'value']);

                return $dict;
            })->keyBy('code');
        });
    }

    public static function clearCache(): void
    {
        Cache::forget(self::CACHE_ALL_KEY);
    }
}
